Technical Field
Embodiments described herein generally relate to processors. In particular, embodiments described herein generally relate to processors to perform return instructions.
Background Information
Return-oriented programming (ROP) is a computer security exploit technique that attackers can use to gain control over computer systems or other electronic devices. In ROP the attackers may gain control of the stack in order to hijack program control flow.
Control of the call stack is often achieved through a buffer overrun exploit or attack. In a buffer overrun, a function that does not sufficiently perform bounds checking before storing data into memory may accept more data than can be properly stored. For example, an attacker may send more data to a web browser than the web browser can properly store. If the data is being stored on the stack, some data may exceed the storage space allocated to that function's variables and overwrite the return address. The return address is an address that is stored on the stack by a call procedure instruction, which is intended to be used to redirect control flow back to the calling function after the called procedure has finished. However, in a buffer overrun attack or exploit, the return address may be overwritten with a different return address. This may allow the attacker to divert control flow to the different return address, execute code starting at the different return address, and perform potentially undesirable and/or malicious actions.
In an ROP attack, the attacker may chain together sequences of what are known as “gadgets.” Each gadget may represent a set of one or a few instructions followed by a return from procedure instruction. The attacker may scan or examine various executable memory regions of code in order to locate or identify desired gadgets. Examples of such executable memory regions of code include, for example, applications, shared user-level libraries, drivers, system level code, and system-level libraries. As an example, the attacker may scan for the opcode 0xC3 corresponding to the return from procedure (RET) instruction as described in Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 2, Instruction Set Reference, A-Z, Order Number 325383-041US, December 2011. After identifying each opcode, the attacker may look to see if the preceding instruction(s) are useful as a gadget. By way of example, the attacker may identify a pop stack instruction followed by a return instruction as a first gadget, a register-to-register move instruction followed by a return instruction as a second gadget, and so on. In some cases, the attacker may be able to identify enough gadgets to form a so-called Turing-complete gadget catalog, which may allow the attacker to perform a wide variety or potentially almost any desired malicious actions.
FIG. 1 is a block diagram of an example three gadget chain 100. The chain includes a first gadget 101 that includes a pop eax instruction 102 and a first return from procedure (RET) instruction 103. The first gadget links to a second gadget 104. The second gadget includes a pop ecx instruction 105 and a second return from procedure instruction 106. The first and second gadgets pop data from the stack into the eax and ecx registers. The second gadget links to a third gadget 107. The third gadget includes a mov [ecx], eax instruction 108 and a third return from procedure instruction 109. The third gadget stores the value in register eax to the memory location indicated by the register ecx. The gadgets may be located in code 110 of potentially different types, such as applications, libraries, drivers, the operating system, etc. This is just one simple illustrative example of a gadget chain.
A rough but illustrative analogy is to consider the gadgets of ROP as somewhat analogous to individual letters cut out from different magazines or newspapers and used to spell a ransom note. Just as the individual letters are cut out of different magazines or newspapers and arranged in series to spell out the ransom note, individual gadgets (e.g., each including one or a few instructions followed by a return) are identified in potentially different pieces of code and linked together to create new code with different functionality. The Turing-complete functionality of gadgets may be somewhat analogous to having all the letters A through Z that are needed to spell out any desired message in that by an analogy they may be used to achieve almost any functionality.
Initially the buffer overrun attack may be used to hijack the return address on the stack and thereby hijack control flow. The address of the first instruction of the first gadget may be stored on the stack to divert the control flow to the first gadget. Instead of returning to the calling procedure (with the call procedure instruction), the control flow may transfer to the first instruction of the first gadget. Next, the return address of the first instruction of the second gadget in the chain may be stored on the stack. The return instruction of the first gadget may divert control flow to the second gadget. In this way, the return addresses of a series of gadgets may be sequentially stored on the stack and jumped to by the return instructions of the chained gadgets. By chaining the gadgets together in particular orders, the attacker may be able to create new program functionalities from pre-existing code. The attackers may potentially use this for undesirable or harmful purposes, such as, for example, stealing confidential information, interfering with or attacking other applications, sending emails, sending text messages, posting tweets, exploiting kernel vulnerabilities, etc.